#!/bin/bash
# Program:
#  主要用来处理视频相关的一些东西
# History:
# 2017-05-18 zmqc First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# FS 输入字段分隔符
# IGNORECASE 控制大小写敏感 0（大小写敏感）
# NF 当前记录中的字段个数
# NR 已经读出的记录数
# OFS 输出字段分隔符
# ORS 输出的记录分隔符
# RS 输入的记录的分隔符

# 功能
# 使用：video concat 1.mp4 2.mp4..., out.mpt
# 最后一个个参数是生成文件的名字， 前面的是待组合的文件名
# 待组合的名字起的尽可能简单些
# 移动当前目录下的一些文件到 .videoconcattmp 目录下，并重命名为 1, 2, 3 加上相应的后缀
# 同时在 .videoconcattmp/mpjt 文件里写入 'file 1.mp4' 这样的行，
# 以便 ffmpeg 合并视频时使用

function concat() {
    [ -d videoconcattmp ]      && rm -rf videoconcattmp

    mkdir videoconcattmp
    touch videoconcattmp/mpjt

    i=1
    for var in $@
    do
        mi=$i"."`echo $var |cut -d'.' -f2`
        name=videoconcattmp/$i"."`echo $var |cut -d'.' -f2`
        if [ $i != $# ]; then
            echo "file '$mi'" >> videoconcattmp/mpjt
            mv $var $name
        else
            echo $var
        fi
        i=$((i+1))
    done
    ffmpeg -f concat -i videoconcattmp/mpjt -c copy $var


    # 还原文件名
    i=1
    for var in $@
    do
        name=videoconcattmp/$i"."`echo $var |cut -d'.' -f2`
        if [ $i != $# ]; then
            mv $name $var
        fi
        i=$((i+1))
    done

    rm -rf videoconcattmp
}

# 参数为 start_time, end_time
# 使用 count_time $start_time $end_time
function count_time() {
    echo -e $1"\n"$2|awk '
           BEGIN{FS=":";RS="\n";
                 starttime=0; endtime=0;
                 hour=0; min=0; second=0;}
           {
             if (NF == 3) {
                 hour   =  $1;
                 min    =  $2;
                 second =  $3;
             } else if (NF == 2 ){
               min    = $1;
               second = $2;
             } else {
               second = $1;
             }

             if (NR == 1) {
                 starttime = hour * 60 * 60 + min * 60 + second;
                 hour = 0;
             } else {
                 endtime = hour * 60 * 60 + min * 60 + second;
             }

           }
           END{print endtime - starttime;}'
}

# 剪切视频
# cut_video starttime endtime input.mp4 [ouput.mp4]
function cut_video() {
    output="output.mp4"
    if [ "$#" == "4" ]; then
        output=$4
    fi
    count=`count_time $1 $2`
    ffmpeg -ss $1 -t $count -i $3 -vcodec copy -acodec copy $output
}

# 将视频转换成 gif
function vgif() {
    palette="/tmp/palette.png"
    filters="fps=15,scale=768:-1:flags=lanczos"

    output="out.gif"
    if [ "$#" == "2" ]; then
        output=$2
    elif [ "$#" == "4" ]; then
        output=$4
    fi

    if [ "$#" -le 2 ];then
        ffmpeg -v warning -i $1 -vf "$filters,palettegen" -y $palette
        ffmpeg -v warning -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $output
    else
        duration=`count_time $1 $2`
        ffmpeg -v warning -ss $1 -t $duration -i $3 -vf "$filters,palettegen" -y $palette
        ffmpeg -v warning -ss $2 -t $duration -i $3 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $output
    fi
}

# 录制视频
function record() {
    output="/tmp/out.mp4"
    if [ "$#" == "1" ]; then
        output=$1
    fi
    #ffmpeg -f x11grab -video_size cif -s xga -framerate 25 -i :0.0+38,63 $output
    # 执行 xwinfo Absolute upper-left X: 110
    #             Absolute upper-left Y: 102
    #             Width                : 656
    #             Height               : 434
    # 返回 X, Y, Width, Height 的组合， 如 “110 102 656 434”
    xywh=`xwininfo |awk 'BEGIN{FS=":";RS="\n";xywh="";}/Absolute|Width|Height/{xywh=xywh$2}END{print xywh}'`
    i=0
    for var in $xywh
    do
        i=$((i+1))
        if [ $i == 1 ]; then
            index=$var
        elif [ $i == 2 ]; then
            index=":0.0+"$index","$var
        elif [ $i == 3 ]; then
            s=$var
        else
            s=$s"x"$var
        fi
    done


    ffmpeg -f x11grab -video_size cif -s $s -framerate 25 -i $index $output
}


# 录制 gif
function gif() {
    record
    if [ $# == 1 ]; then
        vgif "/tmp/out.mp4" $1
    else
        vgif "/tmp/out.mp4"
    fi
}

# 参数分别为时间和输出名字
function byzanz_record() {
    # duration 就是时长，x 和 y 就是坐标，截取画面左上角的值，
    # width 和 height 就是截取画面的寛和高，也就是画面的大小，最后就是输出文件的名字。
    output="byzanz_record.gif"
    if [ $# == 2 ]; then
        output=$2
    fi
    # 返回 X, Y, Width, Height 的组合， 如 “110 102 656 434”
    xywh=`xwininfo |awk 'BEGIN{FS=":";RS="\n";xywh="";}/Absolute|Width|Height/{xywh=xywh$2}END{print xywh}'`
    i=0
    for var in $xywh
    do
        i=$((i+1))
        if [ $i == 1 ]; then
            index="--x="$var
        elif [ $i == 2 ]; then
            index=$index" --y="$var
        elif [ $i == 3 ]; then
            index=$index" --width="$var
        else
            index=$index" --height="$var
        fi
    done
    sleep 3			# 给点时间准备

    #byzanz-record --duration=$1 --x=100 --y=200 --width=700 --height=400 $output
    byzanz-record --duration=$1 --delay=3 -v $index $output

}

# 去除水印
function remove_mark() {
    outputname="output.mp4"
    inputname=$1
    if [ "$#" == "2" ]; then
        outputname=$2
    fi
    # 测试
    while [ "${answer}" != "y" ]
    do
        read -p "x y w h: "  x y w h
        ffplay -i $inputname -vf delogo=x=$x:y=$y:w=$w:h=$h:show=1
        read -p "Please input[y/n] : " answer
    done
    # 通过
    ffmpeg -i $inputname -vf delogo=x=$x:y=$y:w=$w:h=$h -acodec copy $outputname
}


# 抽取图片（截图）
function capture() {
    start=$1
    end=$2
    inputname=$3
    count=`count_time $1 $2`
    outputname=${4}image-${inputname%.*}`count_time 0 $2`%d.jpg
    ffmpeg -ss $start -t $count -i $inputname -r 3 -q:v 2 -f image2 $outputname
}

# 功能: 抽取音频
# 使用 video extract_music input.mp4 [output.mp3]
# 或者 video extract_music [1:00] [2:00] input.mp4 [output.mp3]
function extract_music {
    output="output.mp3"
    if [ "$#" == "2" ]; then
        output=$2
    elif [ "$#" == 4 ]; then
        output=$4
    fi

    if [ "$#" -le 2 ]; then
        ffmpeg -i $1 -vn $output
    else
        duration=`count_time $1 $2`
        ffmpeg -ss $1 -t $duration -i $3 -vn $output
    fi
}

# 功能：抽取视频（去除音频）
# 使用 video extract_video input.mp4 [output.mp3]
# 或者 video extract_video [1:00] [2:00] input.mp4 [output.mp3]
function extract_video {
    output="output.mp4"
    if [ "$#" == "2" ]; then
        output=$2
    elif [ "$#" == 4 ]; then
        output=$4
    fi

    if [ "$#" -le 2 ]; then
        ffmpeg -i $1 -vcodec copy -an $output
    else
        duration=`count_time $1 $2`
        ffmpeg -ss $1 -t $duration -i $3 -vcodec copy -an $output
    fi
}

# 下载 m3u8 视频
function downm3u8() {
    output="output.mp4"
    if [ "$#" == "2" ]; then
        output=$2
    fi
    ffmpeg -i $1 -c copy -bsf:a aac_adtstoasc -movflags frag_keyframe $output
}

# 合并视频和音频
# video merge_music_video input.mp3 input.mp4 [output.mp4]
function merge_music_video() {
    output="output.mp4"
    if [ "$#" == "3" ]; then
	output=$3
    fi
    echo $output
    ffmpeg -i $2 -i $1 -vcodec copy -acodec copy $output
}

# 帮助信息
function help() {
    echo -e "help:         查看 video 的参数介绍, 加中括号表示参数可选 "
    echo -e "concat:       video concat 1.mp4 2.mp4..., out.mp4
              最后一个个参数是生成文件的名字， 前面的是待组合的文件名
              待组合的名字起的尽可能简单些"
    echo -e "cut:          video cut starttime endtime input.mp4 [ouput.mp4]
              剪切视频或者音乐 starttime:开始时间， endtime:结束时间。
              input:待处理视频， ouput:处理后的新视频"
    echo -e "record:       video record [output.mp4] 录制视频，默认生成 /tmp/out.mp4
              作用: 录制视频"
    echo -e "vgif:         video vgif [starttime] [endtime] input.mp4 [output.gif]
              作用：将视频转换 gif"
    echo -e "gif:          video gif  [output.gif]
              作用：录制 gif"
    echo -e "byzanz_record:video byzanz_record duration [output.gif]
              duration 是需要录制的时间
              作用：使用 byzanz 录制 gif，注：会有 3 秒左右的等待时间。
              该参数无效时尝试 apt install byzanz"
    echo -e "remove_mark:  video remove_mark input.mp4 [output.mp4]
              x,y：水印的左上方坐标, w,h: 水印的宽高"
    echo -e "capture:      video capture starttime endtime input.mp4 [dir/]
              截图，在 input.mp4 中从 starttime 到 endtime 抽取图片保存在 dir/ 中"
    echo -e "downm3u8:     video downm3u8 index.m3u8 [output.mp4]
              下载 m3u8 视频"
    echo -e "extract_music:video extract_music [starttime] [endtime] input.mp4 [output.mp3]
              提取音频"
    echo -e "extract_video:video extract_video [starttime] [endtime] input.mp4 [output.mp4]
              提取视频"
    echo -e "merge_music_video: video merge_music_video input.mp3 input.mp4 [output.mp4]
              合并视频和音频"
}


# 针对不同参数进行处理
case $1 in
    "help")
        help
        ;;
    "concat")
        shift
        concat $@
        ;;
    "cut")
        shift
        cut_video $@
        ;;
    "vgif")
        shift
        vgif $@
        ;;
    "gif")
        shift
        gif $@
        ;;
    "record")
        shift
        record $@
        ;;
    "byzanz_record")
        shift
        byzanz_record $@
        ;;
    "count_time")
        shift
        count_time $@
        ;;
    "remove_mark")
        shift
        remove_mark $@
        ;;
    "capture")
        shift
        capture $@
        ;;
    "downm3u8")
        shift
        downm3u8 $@
        ;;
    "extract_music")
        shift
        extract_music $@
        ;;
    "extract_video")
        shift
        extract_video $@
        ;;
    "merge_music_video")
	shift
	merge_music_video $@
	;;
    *)
        echo "        参数错误"
        help
        ;;
esac
